﻿using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Volo.Abp.DependencyInjection;
using Volo.Abp;

namespace CTP.CRM.Core.SharedModel.InternalCore.Token
{
    public class TokenValidator : ITokenValidator, ISingletonDependency
    {
        public ValidatorResult Validator(string key, string token)
        {
            if (token.Contains("Bearer")) token = token.ReplaceFirst("Bearer", "").TrimStart();

            ClaimsPrincipal principal = default!;
            var tokenHandler = new JwtSecurityTokenHandler();
            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
            SecurityToken? validatedToken = null;

            if (tokenHandler.CanReadToken(token))
            {
                try
                {
                    var secretKey = Encoding.UTF8.GetBytes(key);

                    TokenValidationParameters validationParameters = new TokenValidationParameters();
                    validationParameters.IssuerSigningKey = new SymmetricSecurityKey(secretKey);
                    validationParameters.ValidateIssuerSigningKey = true;
                    validationParameters.ValidateIssuer = false;
                    validationParameters.ValidateAudience = false;
                    validationParameters.ValidateLifetime = true;
                    validationParameters.ClockSkew = TimeSpan.Zero;
                    principal = tokenHandler.ValidateToken(token, validationParameters, out validatedToken);
                    return new ValidatorResult(principal);
                }
                catch (SecurityTokenExpiredException)
                {
                    throw new BusinessException(code: "401", message: "登录信息已失效，请重新登录!");
                }
                catch (Exception)
                {
                    throw new BusinessException(code: "401", message: "解析Token失败，请联系管理员.");
                }
            }
            throw new BusinessException(code: "401", message: "读取到不合法凭证,请联系管理员!");
        }

        public async ValueTask<ValidatorResult> ValidatorAsync(string key, string token)
        {
            return await ValueTask.FromResult<ValidatorResult>(Validator(key, token));
        }
    }
}
